package controller

import (
	"errors"
	"fmt"
	"github.com/cy77cc/hioshop/forms"
	"github.com/cy77cc/hioshop/models"
	"github.com/cy77cc/hioshop/utils"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type GoodsHandler struct{}

func (*GoodsHandler) GetDetail(ctx *gin.Context) {
	queryId := ctx.Query("id")
	res := utils.NewResponse()
	id, exits := ctx.Get("id")
	if !exits {
		res.SetRes(1, "id不存在", nil)
		ctx.JSON(http.StatusBadRequest, res)
		return
	}

	userId := id.(uint)

	if queryId == "" {
		res.SetRes(1, "请求参数错误", nil)
		ctx.JSON(http.StatusOK, res)
		return
	}

	goods := models.Goods{}
	goodsId, _ := strconv.Atoi(queryId)
	goods.ID = uint(goodsId)
	err := goods.GetDetail()
	if (err != nil && errors.Is(err, gorm.ErrRecordNotFound)) || goods.ID < 1 {
		res.SetRes(1, "商品已下架或不存在", nil)
		ctx.JSON(http.StatusOK, res)
		return
	}

	gallery := models.GoodsGallery{}
	galleryList, err := gallery.GetGoodsGalleryByGoodsId(goods.ID)
	if err != nil {
		res.SetRes(1, "数据库发生错误", err)
		ctx.JSON(http.StatusOK, res)
		return
	}

	footPrint := models.Footprint{}
	footPrint.UserId = userId
	footPrint.GoodsId = goods.ID
	err = footPrint.AddFootprint()
	if err != nil {
		res.SetRes(1, "数据库发生错误", err)
		ctx.JSON(http.StatusOK, res)
		return
	}

	product := models.Product{}
	product.GoodsId = goods.ID
	productList, err := product.GetProductList()
	if err != nil {
		res.SetRes(1, "数据库发生错误", err)
		ctx.JSON(http.StatusOK, res)
		return
	}

	var goodsNumber uint = 0
	for _, v := range productList {
		if v.GoodsNumber > 0 {
			goodsNumber += v.GoodsNumber
		}
	}

	goodsSpecification := models.GoodsSpecification{}
	specification := models.Specification{}
	list, err := goodsSpecification.GetGoodsSpecificationById(goods.ID)
	if err != nil {
		res.SetRes(1, "数据库发生错误", err)
		ctx.JSON(http.StatusOK, res)
		return
	}
	s, err := specification.GetSpecificationById(list[0].SpecificationId)

	if err != nil {
		res.SetRes(1, "数据库发生错误", err)
		ctx.JSON(http.StatusOK, res)
		return
	}

	data := make(map[string]any)
	data["info"] = goods
	data["gallery"] = galleryList
	data["specificationList"] = forms.SpecificationList{
		SpecificationId: s.ID,
		Name:            s.Name,
		ValueList:       list,
	}
	data["productList"] = productList

	res.SetRes(0, "success", data)
	ctx.JSON(http.StatusOK, res)

}

func (*GoodsHandler) GetGoodsList(ctx *gin.Context) {

	res := utils.NewResponse()
	id, exits := ctx.Get("id")
	if !exits {
		res.SetRes(1, "id不存在", nil)
		ctx.JSON(http.StatusBadRequest, res)
		return
	}

	userId := id.(uint)
	keyword := ctx.Query("keyword")
	sort := ctx.Query("sort")
	order := ctx.Query("order")
	sales := ctx.Query("sale")

	// searchHistory model
	searchHistory := models.SearchHistory{}
	searchHistory.UserId = fmt.Sprintf("%d", userId)
	searchHistory.Keyword = keyword
	searchHistory.AddTime = int(time.Now().Unix() / 1000)

	// 关键词不为空则添加
	if keyword != "" {
		err := searchHistory.Add()
		if err != nil {
			res.SetRes(1, "关键词添加失败", err)
			ctx.JSON(http.StatusOK, res)
			return
		}
	}

	// 排序规则
	orderStr := ""
	if sort == "price" {
		orderStr = "retail_price " + order
	} else if sort == "sales" {
		orderStr = "sell_volume " + sales
	} else {
		orderStr = "sort_order asc"
	}

	goods := models.Goods{}

	goodsData, err := goods.GetGoodsByKeyword(keyword, orderStr)
	if err != nil {
		res.SetRes(1, "查找商品为空", err)
		ctx.JSON(http.StatusOK, res)
		return
	}
	res.SetRes(0, "success", goodsData)
	ctx.JSON(http.StatusOK, res)
}

func (*GoodsHandler) GoodsCount(ctx *gin.Context) {
	goods := models.Goods{}
	res := utils.NewResponse()
	num, err := goods.GetGoodsNum(map[string]any{})
	if err != nil {
		res.SetRes(1, "查询失败", err)
		ctx.JSON(http.StatusOK, res)
	}

	data := map[string]any{
		"goodsCount": num,
	}

	res.SetRes(0, "success", data)
	ctx.JSON(http.StatusOK, res)
}

func (*GoodsHandler) GoodsDetail(ctx *gin.Context) {
	goods := models.Goods{}
	id := ctx.Query("id")
	res := utils.NewResponse()
	goodsId, err := strconv.Atoi(id)
	if err != nil {
		res.SetRes(1, "参数转换失败", err)
		ctx.JSON(http.StatusOK, res)
		return
	}
	goods.ID = uint(goodsId)
	err = goods.GetDetail()
	if err != nil {
		res.SetRes(1, "查询失败", err)
		ctx.JSON(http.StatusOK, res)
		return
	}

	data := map[string]any{
		"info": goods,
	}
	res.SetRes(0, "success", data)
	ctx.JSON(http.StatusOK, res)
}

func (*GoodsHandler) GetAllGoods(ctx *gin.Context) {
	page := ctx.Query("page")
	size := ctx.Query("size")

	expr := map[string]any{}
	paths := strings.Split(strings.Split(ctx.FullPath(), "?")[0], "/")

	if len(paths) == 4 {
		if paths[3] == "onsale" {
			expr["is_on_sale"] = 1
		} else if paths[3] == "out" {
			expr["has_done"] = 1
		} else {
			expr["is_on_sale"] = 0
		}
	}

	res := utils.NewResponse()

	p, _ := strconv.Atoi(page)
	pageSize, _ := strconv.Atoi(size)

	goods := models.Goods{}

	list, err := goods.GetGoodsAll(p, pageSize, expr)
	count, err := goods.GetGoodsNum(expr)
	if err != nil {
		res.SetRes(1, "查询商品信息发生错误", err)
		ctx.JSON(http.StatusOK, res)
		return
	}

	m := make(map[string]any, 3)
	m["currentPage"] = page
	m["count"] = count
	m["data"] = list

	res.SetRes(0, "success", m)
	ctx.JSON(http.StatusOK, res)
}
